package javax.per.toolkit.pool;

public class TaskQueue<T> {
	
	private QueueNode firstNode;
	private QueueNode endNode;
	private int count;
	
	public TaskQueue(){
		this.endNode=null;
		this.firstNode=null;
		count=0;
	}
	
	private class QueueNode{
		T node;
		QueueNode next;
		QueueNode previous;
	}
	
	synchronized public void addLast(T node){
		QueueNode qn=new QueueNode();
		qn.node=node;
		qn.next=null;
		if(this.count==0){
			this.firstNode=qn;
			this.endNode=qn;
			qn.previous=null;
		}else{
			System.err.println(this.endNode);
			System.err.println(qn);
			this.endNode.next=qn;
			qn.previous=this.endNode;
			this.endNode=qn;
		}
		this.count++;
	}
	
	synchronized public void addFirst(T node){
		QueueNode qn=new QueueNode();
		qn.node=node;
		qn.next=null;
		qn.previous=null;
		if(this.count==0){
			this.firstNode=qn;
			this.endNode=qn;
		}else{
			qn.next=this.firstNode;
			this.firstNode.previous=qn;
			this.firstNode=qn;
		}
		this.count++;
	}
	
	synchronized public T pollFirst(){
		if(this.isEmpty())
			return null;
		if(this.count==1){
			QueueNode qn=this.firstNode;
			this.firstNode=null;
			this.endNode=null;
			this.count--;
			return qn.node;
		}else{
			QueueNode qn=this.firstNode;
			this.firstNode=this.firstNode.next;
			this.firstNode.previous=null;
			qn.next=null;
			this.count--;
			return qn.node;
		}
	}
	
	synchronized public T pollLast(){
		if(this.isEmpty())
			return null;
		if(this.count==1){
			QueueNode qn=this.endNode;
			this.firstNode=null;
			this.endNode=null;
			this.count--;
			return qn.node;
		}else{
			QueueNode qn=this.endNode;
			this.endNode=this.endNode.previous;
			this.endNode.next=null;
			qn.previous=null;
			this.count--;
			return qn.node;
		}
	}
	
	synchronized public T remove(T obj){
		if(this.count==0){
			System.err.println("error1");
			return null;
		}else{
			QueueNode point=this.firstNode;
			while(point!=null){
				if(point.node==obj){
					if(point.previous!=null&&point.next!=null){
						point.previous.next=point.next;
						point.next.previous=point.previous;
						point.previous=null;
						point.next=null;
					}else if(point.previous==null&&point.next==null){
						this.endNode=null;
						this.firstNode=null;
					}else if(point.previous==null){
						this.firstNode=point.next;
						point.next=null;
					}else{
						this.endNode=point.previous;
						point.previous=null;
					}
					this.count--;
					return point.node;
				}
				point=point.next;
			}
			System.err.println("error2");
			return null;
		}
	}
	
	public void clear(){
		while(this.firstNode!=this.endNode){
			QueueNode qn=this.firstNode;
			this.firstNode=this.firstNode.next;
			qn.next=null;
			this.count--;
		}
		this.firstNode=null;
		this.endNode=null;
	}
	
	public int size(){
		return this.count;
	}
	
	public boolean isEmpty(){
		if(this.count==0){
			return true;
		}else{
			return false;
		}
	}
	
}
